package com.greateamd.timetableasy.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.greateamd.timetableasy.client.mvc.controller.IMainController;
import com.greateamd.timetableasy.client.mvc.controller.MainController;
import com.greateamd.timetableasy.client.mvc.view.TimeTableasyPage;
import com.greateamd.timetableasy.client.services.login.LoginService;
import com.greateamd.timetableasy.client.services.login.LoginServiceAsync;
import com.greateamd.timetableasy.client.services.user.UserService;
import com.greateamd.timetableasy.client.services.user.UserServiceAsync;
import com.greateamd.timetableasy.client.services.util.ServerCall;
import com.greateamd.timetableasy.client.widgets.login.LoginPanel;
import com.greateamd.timetableasy.domain.User;

public class Framework implements ValueChangeHandler<String> {

	/*
	 * Singleton
	 */
	private static Framework instance = new Framework();
	public static Framework get() {
		return instance;
	}

	private User user;
	
	/**
	 * Constructor for initialising the singleton Framework instance
	 */
	private Framework(){
		initLoginRequestCommand();
		initHistoryStuff();
	}

	public void load(){
		setUser();
	}
	
	private void initHistoryStuff() {
		GWT.log("Add framework history handler");
		History.addValueChangeHandler(this);
	}

	private void initLoginRequestCommand() {
		GWT.log("Injecting login request command");
		ServerCall.setLoginRequestCommand(LoginPanel.cmdOfferLoginPopup);
	}
	

	//-------------------------------------------------------------
	//------------------------ Manage history
	
	@Override
	public void onValueChange(ValueChangeEvent<String> event) {
		if(event.getValue().equals("")){
			MainController.getInstance().onPageRequest(TimeTableasyPage.HOME);
		}
		if(event.getValue().equals("logout")){
			redirectByReplace("/timetableasy/logout");
		}
		for(TimeTableasyPage page : TimeTableasyPage.values()){
			if(event.getValue().equals(page.location)){
				MainController.getInstance().onPageRequest(page);
			}
		}
	}
	
	public void setLocation(String token){
		History.newItem(token,false);
	}

	//-------------------------------------------------------------
	//------------------------ Functionality
	
	public boolean isAuth(){
		return (getUser()==null)? false:true;
	}
	
	private static void redirectByHistory(String url){
		History.newItem(url);
	}

	private native void redirectByReplace(String url) /*-{
	    $wnd.location.replace(url);
	}-*/;
	
	public native void reloadModule() /*-{ 
        $wnd.location.reload(); 
    }-*/; 
	
	//-------------------------------------------------------------
	//------------------------ Manage user
	
	public void setUser() {
		final LoginServiceAsync loginService = GWT.create(LoginService.class);
		new ServerCall<User>(){
			@Override
			protected void callService(AsyncCallback<User> asyncCallback) {
				loginService.getUser(asyncCallback);
			}
			@Override
			public void onSuccess(User result) {
				setUser(result);
			}
		}.call();
	}
	public void setUser(final String username){
		final UserServiceAsync userService = GWT.create(UserService.class);
		new ServerCall<User>(){
			@Override
			protected void callService(AsyncCallback<User> asyncCallback) {
				userService.find(username, asyncCallback);
			}
			@Override
			public void onSuccess(User result) {
				setUser(result);
			}
		}.call();
	}

	private void setUser(User newUser){
		IMainController c = MainController.getInstance();
		c.onUserChange(newUser);
		History.fireCurrentHistoryState();
	}
	
	public User getUser() {
		return user;
	}
}
